package org.warehouse.controller;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.logging.Logger;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.warehouse.service.IService;
import org.warehouse.service.Service;
import org.warehouse.util.Sort;
import org.warehouse.util.WarehouseConstants;

/**
 * It's a dispatcher request<br>
 * Servers for process and preparing data before preparing for view these in the controller's
 */
@WebFilter("/products/*")
public class ProductsFilter implements Filter {
	
	private final Logger logger = Logger.getLogger(ProductsFilter.class.getSimpleName());

	public IService service;
	
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

		HttpServletRequest request = (HttpServletRequest) req;
		HttpSession session = request.getSession(false);
		if (session == null) {
			chain.doFilter(req, res);
			return;
		}
		
		// Store current group id as session value
		String currentGroupIdString = request.getParameter(Keys.CURRENT_GROUP_KEY);
		if (currentGroupIdString != null) {
			int currentGroupId = Integer.valueOf(currentGroupIdString);
			if (currentGroupId != (Integer) session.getAttribute(Keys.CURRENT_GROUP_KEY)) {
				logger.info("Store new id of a current group " + currentGroupId);
				session.setAttribute(Keys.CURRENT_GROUP_KEY, Integer.valueOf(currentGroupId));
				
				// Dispose current page number to 0 and start index to 1
				session.setAttribute(Keys.CURRENT_PAGE_KEY, 0);
				session.setAttribute(Keys.PAGE_START_INDEX_OF_KEY, 1);
			}
		}

		// Store current page number
		String currentPage = request.getParameter(Keys.CURRENT_PAGE_KEY);
		if (currentPage != null) {
			logger.info("Store new page number " + currentPage);
			session.setAttribute(Keys.CURRENT_PAGE_KEY, Integer.valueOf(currentPage));
		}
		
		// Change sort ordering only if 
		String lastSortCoumnName = request.getParameter(Keys.LAST_SORT_COLUMN_NAME_KEY);
		if (lastSortCoumnName != null) {
			session.setAttribute(Keys.LAST_SORT_COLUMN_NAME_KEY, lastSortCoumnName);

			// Swap sort ordering
			String key = lastSortCoumnName.equals("PRODUCT_NAME") ? Keys.CURRENT_NAME_SORT_KEY : Keys.CURRENT_PRICE_SORT_KEY;
			Sort oldSort = Sort.valueOf((String) session.getAttribute(key));
			logger.info(MessageFormat.format("Swap ordering for column {0} from {1} to {2}", lastSortCoumnName, oldSort, oldSort.swap()));
			session.setAttribute(key, oldSort.swap().name());
		}
		
		// Page navigation
		String pageNagivate = request.getParameter(Keys.PAGE_NAVIGATE_KEY);
		if (pageNagivate != null) {
			int startIndex = (Integer) session.getAttribute(Keys.PAGE_START_INDEX_OF_KEY);
			int newStartIndex;
			if (pageNagivate.equals(Keys.PAGE_NAVIGATE_NEXT_KEY)) {
				newStartIndex = startIndex + WarehouseConstants.PAGES_PER_SCREEN;
			} else {
				newStartIndex = startIndex - WarehouseConstants.PAGES_PER_SCREEN;
			}
			
			// Check new start index
			int groupId = (Integer) session.getAttribute(Keys.CURRENT_GROUP_KEY);
			int countOfProduct = service.getCountOfPages(groupId);
			if (newStartIndex > 0 && newStartIndex <= countOfProduct) {
				logger.info("Store new page start index " + newStartIndex);
				session.setAttribute(Keys.PAGE_START_INDEX_OF_KEY, newStartIndex);
				session.setAttribute(Keys.CURRENT_PAGE_KEY, newStartIndex);
			} else {
				logger.info("New page start index isn't correct. It should be between 1 and " + countOfProduct);
			}
		}

		chain.doFilter(req, res);
	}

	@Override
	public void destroy() {
	}


	@Override
    public void init(FilterConfig filterConfig) throws ServletException {
		service = Service.getInstance();
    }

}
